//
//  BaseModle.m
//  365Locator
//
//  Created by zhikuiyu on 14-11-15.
//  Copyright (c) 2014年 zhikuiyu. All rights reserved.
//

#import "BaseModle.h"
#import <objc/message.h>

@implementation BaseModle
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"

- (void)encodeWithCoder:(NSCoder *)aCoder
{
        
    Class clazz = [self class];
    u_int count;
    objc_property_t* properties = class_copyPropertyList(clazz, &count);
    for (int i = 0; i < count ; i++)
    {
        objc_property_t prop=properties[i];
        const char* propertyName = property_getName(prop);
        id value = [self performSelector:NSSelectorFromString([NSString stringWithUTF8String:propertyName])];

        if(value != nil){
            [aCoder encodeObject:value forKey:[NSString stringWithUTF8String:propertyName]];
        }
    }
    
}

- (NSDictionary *)toDict{

    NSMutableDictionary * dict = [NSMutableDictionary dictionary] ;
    
    Class clazz = [self class];
    u_int count;
    objc_property_t* properties = class_copyPropertyList(clazz, &count);

    for (int i = 0; i < count ; i++)
    {
        objc_property_t prop=properties[i];
        const char* propertyName = property_getName(prop);
        id value = [self performSelector:NSSelectorFromString([NSString stringWithUTF8String:propertyName])];
        
        if(value != nil){
            [dict setObject:value forKey:[NSString stringWithUTF8String:propertyName]];
        }
    }
    
    return dict;
}


- (NSString *)toJSONString{
    
    NSDictionary * dict = [self toDict];
    
    if([NSJSONSerialization isValidJSONObject:dict]){
        NSData  * data = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:nil];
        NSString * jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        return jsonString;
    }
    
    
    return @"";
}


- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super init];
    if (self)
    {
        if(!obserArray)
        {
            obserArray = [[NSMutableArray alloc] init];
        }
        [obserArray removeAllObjects];
        
        Class clazz = [self class];
        u_int count;
        objc_property_t* properties = class_copyPropertyList(clazz, &count);
        for (int i = 0; i < count ; i++)
        {
            objc_property_t prop=properties[i];
            const char* propertyName = property_getName(prop);
            id value = [aDecoder decodeObjectForKey:[NSString stringWithUTF8String:propertyName]];
            if(value != nil){
                NSString * pro = [NSString stringWithUTF8String:propertyName];
                
                pro = [pro stringByReplacingCharactersInRange:NSMakeRange(0,1) withString:[[pro substringToIndex:1] uppercaseString]];
                
                NSString *destMethodName = [NSString stringWithFormat:@"set%@:",pro]; //capitalizedString返回每个单词首字母大写的字符串（每个单词的其余字母转换为小写）
                SEL destMethodSelector = NSSelectorFromString(destMethodName);
                if ([self respondsToSelector:destMethodSelector]) {
                    [self performSelector:destMethodSelector withObject:value];
//                    objc_msgSend(self, destMethodSelector, value);
                }
//                [self addObserver:self forKeyPath:[NSString stringWithUTF8String:propertyName] options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:NULL];
//                [obserArray addObject:[NSString stringWithUTF8String:propertyName]];

            }
        }
    }
    return self;
}


- (void)copyInfoFromModle:(BaseModle *)modle{

    Class clazz = [self class];
    u_int count;
    objc_property_t* properties = class_copyPropertyList(clazz, &count);
    for (int i = 0; i < count ; i++)
    {
        objc_property_t prop=properties[i];
        const char* propertyName = property_getName(prop);

        id newValue = [modle performSelector:NSSelectorFromString([NSString stringWithUTF8String:propertyName])];
        
        NSString *destMethodName = [NSString stringWithFormat:@"set%@:",[[NSString stringWithUTF8String:propertyName] capitalizedString]]; //capitalizedString返回每个单词首字母大写的字符串（每个单词的其余字母转换为小写）
        SEL destMethodSelector = NSSelectorFromString(destMethodName);
        if(newValue != nil){
            if ([self respondsToSelector:destMethodSelector]) {
                [self performSelector:destMethodSelector withObject:newValue];
            }
        }
    }
    
}

- (id)initWithDictionary:(NSDictionary *)dict{
    
    return [self initWithParmDict:dict, nil];
}

- (id)initWithParmDict:(NSDictionary *) child1,... NS_REQUIRES_NIL_TERMINATION{
    if(self = [super init]){
        if([child1 mIsDictionary]){
            NSMutableDictionary * contentDict = [[NSMutableDictionary alloc] initWithDictionary:child1];
            [contentDict addEntriesFromDictionary:child1];
          
            va_list arglist;
            va_start(arglist, child1);
            id arg;
            while((arg = va_arg(arglist, id))) {
                if (arg)
                    [contentDict addEntriesFromDictionary:arg];
            }
            va_end(arglist);
            
            
            NSMutableDictionary * resultDict = [NSMutableDictionary new];
            [self resetData:&resultDict WithDict:contentDict];
            
            [self addParaWithDict:resultDict, nil];
            
        }
        
    }
    
    return self;
    
}

- (void)resetData:(NSMutableDictionary **)resdict WithDict:(NSDictionary *)dict{
    
    for(NSString * key in [dict allKeys]){
        NSString * rKey = key;
        if([rKey isEqualToString:@"id"]){
            rKey = @"ID";
        }
        NSDictionary * obj = [dict objectForKey:rKey];
        if([obj isKindOfClass:[NSDictionary class]]){
            [self resetData:resdict WithDict:obj];
        }else if(obj != nil ){
            [*resdict setObject:obj forKey:rKey];
        }
    }
}

- (void)addParaWithDict:(NSDictionary *)child1,... NS_REQUIRES_NIL_TERMINATION{
    if([child1 mIsDictionary]){
        NSMutableDictionary * contentDict = [[NSMutableDictionary alloc] initWithDictionary:child1];
        [contentDict addEntriesFromDictionary:child1];
        
        if(!obserArray)
        {
            obserArray = [[NSMutableArray alloc] init];
        }
        [obserArray removeAllObjects];
        
        va_list arglist;
        va_start(arglist, child1);
        id arg;
        while((arg = va_arg(arglist, id))) {
            if (arg)
                [contentDict addEntriesFromDictionary:arg];
        }
        va_end(arglist);
        
        for (NSString *keyName in [contentDict allKeys]) {
             NSString *catName = [keyName stringByReplacingCharactersInRange:NSMakeRange(0,1) withString:[[keyName substringToIndex:1] uppercaseString]];

            //构建出属性的set方法
            NSString *destMethodName = [NSString stringWithFormat:@"set%@:",catName]; //capitalizedString返回每个单词首字母大写的字符串（每个单词的其余字母转换为小写）
            SEL destMethodSelector = NSSelectorFromString(destMethodName);
            
            if ([self respondsToSelector:destMethodSelector]) {
                NSObject * obj = [[contentDict objectForKey:keyName] copy];
//                objc_msgSend(self, destMethodSelector,obj );
                [self performSelector:destMethodSelector withObject:obj];
//                [self addObserver:self forKeyPath:keyName options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:NULL];
                [obserArray addObject:keyName];
            }
            
        }
    }
    
    
    
}

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if(_valueChangeBlock){
        _valueChangeBlock(keyPath,[change mObjectForKey:@"new"]);
    }
   
}


#pragma mark copying协议的方法
// 这里创建的副本对象不要求释放
- (id)copyWithZone:(NSZone *)zone {
    NSObject *copy = [[[self class] allocWithZone:zone] init];
    
    Class clazz = [self class];
    u_int count;
    
    Class superClass = [NSObject class];
    u_int s_count ;
    
    
    objc_property_t* properties = class_copyPropertyList(clazz, &count);
    objc_property_t* su_properties = class_copyPropertyList(superClass, &s_count);
    
    for (int i = 0; i < count ; i++)
    {
        objc_property_t prop=properties[i];
        const char* propertyName = property_getName(prop);
        
        BOOL isSuperPro = NO;
        
        for(int j = 0 ; j < s_count ; j++){
            objc_property_t superprop=su_properties[j];
            const char* superpropertyName = property_getName(superprop);
            if([[NSString stringWithUTF8String:propertyName] isEqualToString:[NSString stringWithUTF8String:superpropertyName]]){
                isSuperPro = YES;
                break;
            }
        }
        
        if(isSuperPro){
            continue;
        }
        
        
        NSLog(@"%@",[NSString stringWithUTF8String:propertyName]);
//        id value = objc_msgSend(self, NSSelectorFromString([NSString stringWithUTF8String:propertyName]));
        id value = [self performSelector:NSSelectorFromString([NSString stringWithUTF8String:propertyName])];

        if(value != nil){
            NSString *destMethodName = [NSString stringWithFormat:@"set%@:",[[NSString stringWithUTF8String:propertyName] capitalizedString]]; //capitalizedString返回每个单词首字母大写的字符串（每个单词的其余字母转换为小写）
            SEL destMethodSelector = NSSelectorFromString(destMethodName);

            if ([copy respondsToSelector:destMethodSelector]) {
//                objc_msgSend(copy, destMethodSelector, value);
                [copy performSelector:destMethodSelector withObject:value];
            }
        }
    }
    
    free(properties);
    
    return copy;
}

//- (NSString *)description{
//    Class clazz = [self class];
//    u_int count;
//    
//    NSMutableDictionary * dict = NSMutableDictionary.new ;
//    
//    objc_property_t* properties = class_copyPropertyList(clazz, &count);
//    for (int i = 0; i < count ; i++)
//    {
//        objc_property_t prop=properties[i];
//        const char* propertyName = property_getName(prop);
////        id value = objc_msgSend(self, NSSelectorFromString([NSString stringWithUTF8String:propertyName]));
//        id value = [self performSelector:NSSelectorFromString([NSString stringWithUTF8String:propertyName])];
//
//        if(value != nil){
//            [dict setObject:value forKey:[NSString stringWithUTF8String:propertyName]];
//        }
//    }
//    return [NSString stringWithFormat:@"CLass->%@ %@",[self class],[dict description]];
//}

- (void)dealloc
{
//    for (int i = 0; i < [obserArray mCount] ; i++)
//    {
//        [self removeObserver:self forKeyPath:[obserArray mObjectAtIndex:i]];
//    }
}

@end
